package org.developerworks.web;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ProxyEngineServlet extends HttpServlet
{

	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
	{
		String urlStr = req.getParameter("url");
		proxyRequest(urlStr, req, resp, false);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
	{
		String urlStr = req.getParameter("url");
		proxyRequest(urlStr, req, resp, true);
	}

	private void proxyRequest(String urlStr, HttpServletRequest request, HttpServletResponse response, boolean doPost)
			throws IOException
	{
		try
		{
			URL url = new URL(urlStr);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod(doPost ? "POST" : "GET");
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(true);
			Enumeration<?> names = request.getHeaderNames();
			while (names.hasMoreElements())
			{
				String name = (String) names.nextElement();
				conn.setRequestProperty(name, request.getHeader(name));
			}
			conn.connect();
			if (doPost)
			{
				BufferedInputStream postIn = new BufferedInputStream(request.getInputStream());
				BufferedOutputStream postOut = new BufferedOutputStream(conn.getOutputStream());
				int postData = -1;
				while ((postData = postIn.read()) != -1)
				{
					postOut.write(postData);
				}
				postOut.flush();
				postOut.close();
				postIn.close();
			}
			response.setStatus(conn.getResponseCode());
			for (String name : conn.getHeaderFields().keySet())
			{
				for (String value : conn.getHeaderFields().get(name))
				{
					response.addHeader(name, value);
				}
			}
			BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
			BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
			int streamData = -1;
			while ((streamData = in.read()) != -1)
			{
				out.write(streamData);
			}
			out.flush();
			out.close();
			in.close();
			conn.disconnect();
		}
		catch (MalformedURLException e)
		{
			e.printStackTrace();
		}
	}
}
